/****************************************************************************
 **
 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
 ** Contact: http://www.qt-project.org/legal
 **
 ** This file is part of the examples of the Qt Toolkit.
 **
 ** $QT_BEGIN_LICENSE:BSD$
 ** You may use this file under the terms of the BSD license as follows:
 **
 ** "Redistribution and use in source and binary forms, with or without
 ** modification, are permitted provided that the following conditions are
 ** met:
 **   * Redistributions of source code must retain the above copyright
 **     notice, this list of conditions and the following disclaimer.
 **   * Redistributions in binary form must reproduce the above copyright
 **     notice, this list of conditions and the following disclaimer in
 **     the documentation and/or other materials provided with the
 **     distribution.
 **   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
 **     of its contributors may be used to endorse or promote products derived
 **     from this software without specific prior written permission.
 **
 **
 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 **
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/

 #include <QAudioFormat>
 #include "utils.h"

 qint64 audioDuration(const QAudioFormat &format, qint64 bytes)
 {
     return (bytes * 1000000) /
         (format.frequency() * format.channels() * (format.sampleSize() / 8));
 }

 qint64 audioLength(const QAudioFormat &format, qint64 microSeconds)
 {
    qint64 result = (format.frequency() * format.channels() * (format.sampleSize() / 8))
        * microSeconds / 1000000;
    result -= result % (format.channelCount() * format.sampleSize());
    return result;
 }

 qreal nyquistFrequency(const QAudioFormat &format)
 {
     return format.frequency() / 2;
 }

 QString formatToString(const QAudioFormat &format)
 {
     QString result;

     if (QAudioFormat() != format) {
         if (format.codec() == "audio/pcm") {
             Q_ASSERT(format.sampleType() == QAudioFormat::SignedInt);

             const QString formatEndian = (format.byteOrder() == QAudioFormat::LittleEndian)
                 ?   QString("LE") : QString("BE");

             QString formatType;
             switch(format.sampleType()) {
             case QAudioFormat::SignedInt:
                 formatType = "signed";
                 break;
             case QAudioFormat::UnSignedInt:
                 formatType = "unsigned";
                 break;
             case QAudioFormat::Float:
                 formatType = "float";
                 break;
             case QAudioFormat::Unknown:
                 formatType = "unknown";
                 break;
             }

             QString formatChannels = QString("%1 channels").arg(format.channels());
             switch (format.channels()) {
             case 1:
                 formatChannels = "mono";
                 break;
             case 2:
                 formatChannels = "stereo";
                 break;
             }

             result = QString("%1 Hz %2 bit %3 %4 %5")
                 .arg(format.frequency())
                 .arg(format.sampleSize())
                 .arg(formatType)
                 .arg(formatEndian)
                 .arg(formatChannels);
         } else {
             result = format.codec();
         }
     }

     return result;
 }

 bool isPCM(const QAudioFormat &format)
 {
     return (format.codec() == "audio/pcm");
 }

 bool isPCMS16LE(const QAudioFormat &format)
 {
     return (isPCM(format) &&
             format.sampleType() == QAudioFormat::SignedInt &&
             format.sampleSize() == 16 &&
             format.byteOrder() == QAudioFormat::LittleEndian);
 }

 const qint16  PCMS16MaxValue     =  32767;
 const quint16 PCMS16MaxAmplitude =  32768; // because minimum is -32768

 qreal pcmToReal(qint16 pcm)
 {
     return qreal(pcm) / PCMS16MaxAmplitude;
 }

 qint16 realToPcm(qreal real)
 {
     return real * PCMS16MaxValue;
 }
